#ifndef GIGI_TEST_H__
#define GIGI_TEST_H__

#define TEST_PORT  9543

typedef struct CommTest_Node_t
{
  THREAD_T      thread;
  int           id;
  int           port;
  int           count;
  GIGI_ID       service_id;
  GIGI_SERVICE  service;
  const char*   conn_string;
  GIGIONE       context;
  GIGI_ID*      node_id;
  GIGI_MPI      mpi_object;
  void          (*func)(struct CommTest_Node_t * ctx);
}CommTest_Node;

int CommTest_Start (int size, CommTest_Node * ctx, GIGI_ID * nodes, 
                    const char * conn_string, void(*func)(CommTest_Node*),
                    GIGI_ID service_id, int join);

extern void MPIRegister(GIGIONE comm);
int CommTest_Join(CommTest_Node* ctx,int size);

#ifdef WINDOWS
unsigned long __stdcall CommTest_ThreadProc(void* p);
#else
void* CommTest_ThreadProc(void* p);
#endif

void CommTest_MPI(CommTest_Node* ctx,const char* mpi_name, int nRunCount);

#define COMM_TEST(fclass,fname,sz)                                    \
    void func_##fclass##_##fname(CommTest_Node* ctx);                 \
    C_TEST(fclass,fname){                                             \
    CommTest_Node Nodes[sz]; GIGI_ID IDs[sz]; int rc;                 \
    rc = CommTest_Start(sz,Nodes,IDs,0,func_##fclass##_##fname,0,1);  \
    C_ASSERT_TRUE( rc>=0 ); }                                         \
    void func_##fclass##_##fname(CommTest_Node* ctx)

#define COMM_TEST_WITH_CONN_STR(fclass,fname,sz,cstr)                 \
    void func_##fclass##_##fname(CommTest_Node* ctx);                 \
    C_TEST(fclass,fname){                                             \
    CommTest_Node Nodes[sz]; GIGI_ID IDs[sz]; int rc;                 \
    rc = CommTest_Start(sz,Nodes,IDs,cstr,func_##fclass##_##fname,0,1);\
    C_ASSERT_TRUE ( rc>=0 ); }                                        \
    void func_##fclass##_##fname(CommTest_Node* ctx)


#define MPI_TEST(suite,name,sz,runCount) \
    COMM_TEST(suite, name, sz) { CommTest_MPI(ctx,#name,runCount); };

void print_socket (const char* s, int id, GIGI_SOCKET fd);
void print_ctx_info (CommTest_Node* ctx);
GIGI_SOCKET create_channel (CommTest_Node* ctx, int from, int to);
int create_ring (CommTest_Node* ctx, GIGI_SOCKET* prevFD, GIGI_SOCKET* nextFD);
int close_ring (CommTest_Node* ctx,  GIGI_SOCKET rIN, GIGI_SOCKET rOUT);
int sendrecv_ring (GIGI_SOCKET in, GIGI_SOCKET out, int id,  int type, void* sendBuffer, void* recvBuffer, int nSize);
int sendrecv (GIGI_SOCKET fd,  int type,  void* buffer, int* nSize, int myid, int from, int to);
char* GenTempFileName(char* sFileName, int nSize);
int GenTempFile(const char* sFileName, int nSize);
void remove_file(const char* pFileName);

#endif


